"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.split = exports.curlToJson = void 0;
exports.default = {
    curlToJson: curlToJson,
};
function curlToJson(s) {
    var res = {
        url: '',
        method: '',
        headers: {},
        params: {},
        data: {},
    };
    if (0 != s.indexOf('curl '))
        return res;
    var args = rewrite(exports.split(s));
    res.method = res.method || 'GET';
    var state = '';
    args.forEach(function (arg) {
        switch (true) {
            case isURL(arg):
                var url = new URL(arg);
                res.url = url.origin + url.pathname;
                if (url.search) {
                    var params = new URLSearchParams(url.search);
                    res.params = __assign({}, parseParamsField(params.toString()));
                }
                break;
            case arg === '--data-raw':
                res.method = 'POST';
                state = 'data';
                break;
            case arg === '-A' || arg === '--user-agent':
                state = 'user-agent';
                break;
            case arg === '--data-urlencode':
                state = 'data.urlencode';
                break;
            case arg === '--data-binary':
                state = 'data.binary';
                break;
            case arg === '-F' || arg === '--form':
                state = 'form';
                break;
            case arg === '-H' || arg === '--header':
                state = 'header';
                break;
            case arg === '-d' || arg === '--data' || arg === '--data-ascii' || arg === '--data-raw':
                state = 'data';
                break;
            case arg === '-u' || arg === '--user':
                state = 'user';
                break;
            case arg === '-I' || arg === '--head':
                res.method = 'HEAD';
                break;
            case arg === '-X' || arg === '--request' || arg === '--location':
                state = 'method';
                break;
            case arg === '-b' || arg === '--cookie':
                state = 'cookie';
                break;
            case arg === '--compressed':
                res.headers['Accept-Encoding'] = res.headers['Accept-Encoding'] || 'deflate, gzip';
                break;
            case !!arg:
                switch (state) {
                    case 'header':
                        var field = parseField(arg);
                        field[0] = (field[0] || '').split('-').map(function (item) { return item.charAt(0).toUpperCase() + item.slice(1); }).join('-');
                        res.headers[field[0]] = field[1];
                        state = '';
                        break;
                    case 'user-agent':
                        res.headers['User-Agent'] = arg;
                        state = '';
                        break;
                    case 'data':
                        res.headers['Content-Type'] = res.headers['Content-Type'] || 'application/x-www-form-urlencoded';
                        console.log('arg', arg);
                        res.data = __assign({}, JSON.parse(arg));
                        state = '';
                        break;
                    case 'user':
                        res.headers['Authorization'] = 'Basic ' + btoa(arg);
                        state = '';
                        break;
                    case 'method':
                        res.method = arg;
                        state = '';
                        break;
                    case 'cookie':
                        res.headers['Set-Cookie'] = arg;
                        state = '';
                        break;
                }
                break;
        }
    });
    return res;
}
exports.curlToJson = curlToJson;
function rewrite(args) {
    return args.reduce(function (args, a) {
        if (0 === a.indexOf('-X')) {
            args.push('-X');
            args.push(a.slice(2));
        }
        else {
            args.push(a);
        }
        return args;
    }, []);
}
function parseField(s) {
    return s.split(/: (.+)/);
}
function parseDataUrlencodeField(s) {
    return s.split(/=/);
}
function parseParamsField(s) {
    if (s === "")
        return null;
    var object = {};
    var allParamsArr = s.split(/&/);
    allParamsArr.forEach(function (element) {
        var field = element.split(/=/);
        object[field[0]] = field[1];
    });
    return object;
}
function parseFromField(arg) {
    return arg.split(/=/);
}
function isURL(s) {
    return /^https?:\/\//.test(s) || /^localhost?:/.test(s) || /^127.0.0.1?:/.test(s);
}
var scan = function (string, pattern, callback) {
    var result = "";
    while (string.length > 0) {
        var match = string.match(pattern);
        if (match && match.index != null && match[0] != null) {
            result += string.slice(0, match.index);
            result += callback(match);
            string = string.slice(match.index + match[0].length);
        }
        else {
            result += string;
            string = "";
        }
    }
    return result;
};
var split = function (line) {
    if (line === void 0) { line = ""; }
    var words = [];
    var field = "";
    scan(line, /\s*(?:([^\s\\\'\"]+)|'((?:[^\'\\]|\\.)*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|$)?/, function (match) {
        var _raw = match[0], word = match[1], sq = match[2], dq = match[3], escape = match[4], garbage = match[5], separator = match[6];
        if (garbage != null) {
            throw new Error("Unmatched quote: " + line);
        }
        if (word) {
            field += word;
        }
        else {
            var addition = void 0;
            if (sq) {
                addition = sq;
            }
            else if (dq) {
                addition = dq;
            }
            else if (escape) {
                addition = escape;
            }
            if (addition) {
                field += addition.replace(/\\(?=.)/, "");
            }
        }
        if (separator != null) {
            words.push(field);
            field = "";
        }
    });
    if (field) {
        words.push(field);
    }
    return words;
};
exports.split = split;
